﻿
Imports System.Windows.Forms
Imports System.ComponentModel

<DefaultProperty("Value")> _
Public Class NumericBox
    Private _ValueInteger As Long
    Private _ValueUInteger As ULong
    Private _ValueDecimal As Double

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

    End Sub

    Private _AllowNegative As Boolean
    <DefaultValue(False)> _
    Public Property AllowNegative() As Boolean
        Get
            Return _AllowNegative
        End Get
        Set(ByVal value As Boolean)
            _AllowNegative = value
        End Set
    End Property

    Private _AllowDecimal As Boolean
    <DefaultValue(False)> _
    Public Property AllowDecimal() As Boolean
        Get
            Return _AllowDecimal
        End Get
        Set(ByVal value As Boolean)
            _AllowDecimal = value
            If value = False Then _DecimalDigits = 0
            UpdateVisual()
        End Set
    End Property

    Private _DecimalDigits As UShort
    <DefaultValue(0)> _
    Public Property DecimalDigits() As UShort
        Get
            Return _DecimalDigits
        End Get
        Set(ByVal value As UShort)
            _DecimalDigits = value
            If value = 0 Then
                _AllowDecimal = False
            Else
                _AllowDecimal = True
            End If
            UpdateVisual()
        End Set
    End Property

    <DefaultValue(0)> _
    Public Property Value As String
        Get
            Dim s As String = "0"
            If AllowDecimal Then
                s = _ValueDecimal.ToString("0." & Microsoft.VisualBasic.Left("0000000000000000000", DecimalDigits))
            Else
                If AllowNegative Then
                    s = _ValueInteger.ToString()
                Else
                    s = _ValueUInteger.ToString
                End If
            End If
            s = Replace(s, ",", ".")
            Return s
        End Get
        Set(ByVal value As String)
            If AllowDecimal Then
                _ValueDecimal = Double.Parse(value)
            Else
                If AllowNegative Then
                    _ValueInteger = Long.Parse(value)
                Else
                    _ValueUInteger = ULong.Parse(value)
                End If
            End If
            UpdateVisual()
        End Set
    End Property

    Private Sub TextBox1_KeyPress(sender As Object, e As KeyPressEventArgs) Handles TextBox1.KeyPress
        Dim KeyAscii As Short

        'Convert the KeyChar argument to an Ascii value 
        KeyAscii = Asc(e.KeyChar)
        'Decide what to do based on the AllowedCharacters property 
        If KeyAscii = 44 Then KeyAscii = 46
        If _AllowNegative = False And KeyAscii = 45 Then KeyAscii = 0
        If _AllowDecimal = False And KeyAscii = 46 Then KeyAscii = 0
        Select Case KeyAscii
            Case 48 To 57
            Case Is = 3  ' ctrl c
            Case Is = 8  ' backspace
            Case Is = 13 ' cr
            Case Is = 22 ' ctrl v
            Case Is = 26 ' ctrl z
            Case Is = 43 ' +
                If TextBox1.Text.Length >= 0 Then KeyAscii = 0
            Case Is = 44 ' ,
                If TextBox1.Text.Length >= 0 Then KeyAscii = 0
            Case Is = 45 ' -
                If TextBox1.Text.Length >= 0 Then KeyAscii = 0
            Case Is = 46 ' .
                If TextBox1.Text.Length >= 0 Then KeyAscii = 0
            Case Else
                KeyAscii = 0
        End Select
        e.KeyChar = Chr(KeyAscii)
        MyBase.OnKeyPress(e)
    End Sub
    

    Private Sub UpdateVisual()
        Dim s1 As String = "0"
        Dim s2 As String = "0." & Microsoft.VisualBasic.Left("0000000000000000000", DecimalDigits)
        If AllowDecimal Then
            s1 = _ValueDecimal.ToString(s2)
        Else
            If AllowNegative Then
                s1 = _ValueInteger.ToString
            Else
                s1 = _ValueUInteger.ToString
            End If
        End If
        s1 = Replace(s1, ",", ".")
        TextBox1.Text = s1
    End Sub

    Private Sub TextBox1_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged
        If IsNumeric(TextBox1.Text) Then
            If AllowDecimal Then
                _ValueDecimal = Double.Parse(TextBox1.Text)
            Else
                If AllowNegative Then
                    _ValueInteger = Long.Parse(TextBox1.Text)
                Else
                    _ValueUInteger = ULong.Parse(TextBox1.Text)
                End If
            End If
        Else
            _ValueDecimal = 0 : _ValueInteger = 0 : _ValueUInteger = 0
        End If
    End Sub

    Private Sub NumericBox_Resize(sender As Object, e As EventArgs) Handles Me.Resize
        TextBox1.Width = Me.Width
        TextBox1.Height = Me.Height
    End Sub


End Class
